﻿//-----------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------
// Exo² ffa01
// Copyright (C) 2007-2008 Samuel Lacroix and Raphaël Legouge
//
// Distributed under GNU General Public License
// See the License folder of Exo² for details
//
//
// http://www.codeplex.com/exo2 (eng)
//-----------------------------------------------------------------------------


#ifndef GUI_H
#define GUI_H
#pragma once


namespace GUI {


// Enregistrement des composants du menu
void RegisterComponents();


// CallBack de création des composants
Exo2::CMenuComponent* CreateButtonCallback(void* pUserData);
Exo2::CMenuComponent* CreateCheckBoxCallback(void* pUserData);
Exo2::CMenuComponent* CreateLabelCallback(void* pUserData);
Exo2::CMenuComponent* CreateHorizontalSliderCallback(void* pUserData);
Exo2::CMenuComponent* CreateVerticalSliderCallback(void* pUserData);
Exo2::CMenuComponent* CreateTextButtonCallback(void* pUserData);


// Nos composants :
// Boutton
class CButton : public Exo2::CMenuButton
{
    public:
        static void SetStateSpriteFileName(const tstring& FileName);
        
        static const tstring& GetStateSpriteFileName();
    
    private:
        virtual void LoadStateSprites();
        
        static tstring StateSpriteFileName;
};


// CheckBox
class CCheckBox : public Exo2::CMenuCheckBox
{
    public:
        static void SetStateSpriteFileName(const tstring& FileName);
        
        static const tstring& GetStateSpriteFileName();
    
    private:
        virtual void LoadStateSprites();
        
        static tstring StateSpriteFileName;
};


// Label
class CLabel : public Exo2::CMenuLabel
{

};


// Slider
class CHorizontalSlider : public Exo2::CMenuHorizontalSlider
{
    public:
        CHorizontalSlider();
        static void SetStateSpriteFileName(const tstring& FileName);
        
        static const tstring& GetStateSpriteFileName();

    private:
        virtual void LoadStateSprites();
        
        static tstring StateSpriteFileName;
};



class CVerticalSlider : public Exo2::CMenuVerticalSlider
{
    public:
        CVerticalSlider();
        static void SetStateSpriteFileName(const tstring& FileName);

        static const tstring& GetStateSpriteFileName();

    private:
        virtual void LoadStateSprites();

        static tstring StateSpriteFileName;        
};


// Boutton avec du texte
class CTextButton : public Exo2::CMenuTextButton
{
    public:
        static void SetStateSpriteFileName(const tstring& FileName);
        
        static const tstring& GetStateSpriteFileName();
    
    private:
        virtual void LoadStateSprites();
        
        static tstring StateSpriteFileName;
};


class IMenuData
{
    protected:
        Exo2::CApplication* pApplication;    
    
    public:
        IMenuData(Exo2::CApplication* pApplication) : pApplication(pApplication) {}

        virtual void LoadDataFromComponent() = 0;           // Components -> Data
        virtual void LoadDataFromApplication() = 0;         // Application -> Data
        virtual void UpdateComponentFromData() = 0;         // Components <- Data
        virtual void UpdateApplicationFromData() = 0;       // Application <- Data
};


class CMenuDataManager
{
    public:
        CMenuDataManager() {}
        virtual ~CMenuDataManager() throw() {}
        
        void LoadDataFromComponent(const std::wstring& MenuName);
        void LoadDataFromApplication(const std::wstring& MenuName);
        
        void UpdateComponentFromData(const std::wstring& MenuName);
        void UpdateApplicationFromData(const std::wstring& MenuName);
        
        const boost::shared_ptr<IMenuData>& GetData(const std::wstring& MenuName);
        
        void SetData(const boost::shared_ptr<IMenuData>& pData, const std::wstring& MenuName);
                
    private:
        CMenuDataManager& operator=(const CMenuDataManager);
        CMenuDataManager(const CMenuDataManager&);
                
        // Données
        typedef std::map<std::wstring, boost::shared_ptr<IMenuData> > TMenuData;        // Nom du menu, Données associées
        TMenuData MenuData;
};


class COnResolutionChange : public Exo2::INewResolutionObserver
{
    public:
        COnResolutionChange(CMenuDataManager* pManager) : pMenuDataManager(pManager) {}
        void OnNewResolution();

    private:
        CMenuDataManager* pMenuDataManager;
};


class CMenuDataProfil : public IMenuData
{
    public:
        CMenuDataProfil(Exo2::CApplication* pApplication) : IMenuData(pApplication) {}
    
        std::list<std::wstring> ShipList;
        typedef std::vector<std::pair<std::wstring, boost::shared_ptr<std::list<std::wstring> > > > TActionList;
        TActionList ActionList;
                
        void LoadDataFromComponent();
        void LoadDataFromApplication();
        void UpdateComponentFromData();
        void UpdateApplicationFromData();
};


class CMenuDataHost : public IMenuData
{
    public:
        CMenuDataHost(Exo2::CApplication* pApplication) : IMenuData(pApplication) {}
        
    private:
        void LoadDataFromComponent() {}
        void LoadDataFromApplication() {}
        void UpdateComponentFromData() {}
        void UpdateApplicationFromData() {}
};


class CMenuDataJoin : public IMenuData
{
    public:
        CMenuDataJoin(Exo2::CApplication* pApplication) : IMenuData(pApplication) {}
        
    private:
        void LoadDataFromComponent() {}
        void LoadDataFromApplication() {}
        void UpdateComponentFromData() {}
        void UpdateApplicationFromData() {}
};


class CMenuDataOptions : public IMenuData
{
    public:
        CMenuDataOptions(Exo2::CApplication* pApplication) : IMenuData(pApplication) {}
        // Graphics
        std::list<std::wstring> ResolutionList;
        bool VSync;
        bool Windowed;
        std::list<std::wstring> FiltrationList;
        
        // Audio
        std::list<std::wstring> AudioDeviceList;
        size_t MasterVolume;
        size_t MusicVolume;
        size_t EffectsVolume;
        
        // Physics
        double TimeStep;
        double ParticleLimitation;
        
        void LoadDataFromComponent() {}
        void LoadDataFromApplication();
        void UpdateComponentFromData();
        void UpdateApplicationFromData();
        
};


class CMenuDataCredits : public IMenuData
{
    public:
        CMenuDataCredits(Exo2::CApplication* pApplication) : IMenuData(pApplication) {}
    
    private:
        void LoadDataFromComponent() {}
        void LoadDataFromApplication() {}
        void UpdateComponentFromData() {}
        void UpdateApplicationFromData() {}
};


class CMenuDataExit : public IMenuData
{
    public:
        CMenuDataExit(Exo2::CApplication* pApplication) : IMenuData(pApplication) {}
    
    private:
        void LoadDataFromComponent() {}
        void LoadDataFromApplication() {}
        void UpdateComponentFromData() {}
        void UpdateApplicationFromData() {}
};


// Changement de menu
void OnClickTextButtonProfil(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonHost(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonJoin(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptions(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonCredits(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonExit(Exo2::CMenuComponent* pSender, void* pUserData);
static std::wstring MenuBeforeExit;


// Menu options
// Actions
void OnClickTextButtonOptionsApply(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptionsCancel(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptionsDefaults(Exo2::CMenuComponent* pSender, void* pUserData);
// Actions du sous-menu Graphics
void OnClickTextButtonOptionsGraphicsResolutionPrev(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptionsGraphicsResolutionNext(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickCheckBoxOptionsGraphicsSyncVert(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickCheckBoxOptionsGraphicsWindowed(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptionsGraphicsFiltrationPrev(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptionsGraphicsFiltrationNext(Exo2::CMenuComponent* pSender, void* pUserData);
// Actions du sous-menu Audio
void OnClickTextButtonOptionsAudioDevicePrev(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonOptionsAudioDeviceNext(Exo2::CMenuComponent* pSender, void* pUserData);
void OnChangeSliderOptionsAudioMaster(Exo2::CMenuComponent* pSender, void* pUserData);
void OnChangeSliderOptionsAudioMusic(Exo2::CMenuComponent* pSender, void* pUserData);
void OnChangeSliderOptionsAudioEffects(Exo2::CMenuComponent* pSender, void* pUserData);
// Actions du sous-menu Physics
void OnChangeSliderOptionsPhysicsAccuracy(Exo2::CMenuComponent* pSender, void* pUserData);
void OnChangeSliderOptionsPhysicsParticleLimitation(Exo2::CMenuComponent* pSender, void* pUserData);
// Mise à jour
void OptionsModified();             // Signal au menu que des options ont été modifiées


// Menu Host
// Actions
void OnClickTextButtonHostCreate(Exo2::CMenuComponent* pSender, void* pUserData);


// Menu Join
// Actions
void OnClickTextButtonJoinJoinGame(Exo2::CMenuComponent* pSender, void* pUserData);


// Menu Exit
void OnClickTextButtonExitYes(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonExitNo(Exo2::CMenuComponent* pSender, void* pUserData);


// Menu Profil
void OnClickTextButtonProfilPlayerShipPrev(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickTextButtonProfilPlayerShipNext(Exo2::CMenuComponent* pSender, void* pUserData);
void OnChangeSliderProfilActionScroll(Exo2::CMenuComponent* pSender, void* pUserData);
void OnEnterLabelProfilAction(Exo2::CMenuComponent* pSender, void* pUserData);
void OnLeaveLabelProfilAction(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction0(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction1(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction2(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction3(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction4(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction5(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction6(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction7(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction8(Exo2::CMenuComponent* pSender, void* pUserData);
void OnClickLabelProfilAction9(Exo2::CMenuComponent* pSender, void* pUserData);
// Mise à jour
void ModifingAction();


// Menu Chargement
void OnClickTextButtonLoadingCancel(Exo2::CMenuComponent* pSender, void* pUserData);
static std::wstring MenuBeforeLoading;


}
#include "gui.inl"
#endif